package com.example.theoretical_verification.thread;

import java.util.concurrent.atomic.AtomicInteger;

// 本案例展示了如何使用ThreadLocal。
// 局部变量UserInfo。单独定义在每个线程的工作内存内部。一共有20个，占用空间。其实有点像ThreadLocal了。语法上写的话，是要写到runable实现类的内部的。
public class ThreadLocalExample {

    // 定义一个ThreadLocal对象来存储用户信息
    private static ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>();

    // AtomicInteger用于生成用户ID
    private static AtomicInteger nextUserId = new AtomicInteger(1);

    // 用户信息类
    static class UserInfo {
        private int userId;
        private String username;

        public UserInfo(String username) {
            this.userId = nextUserId.getAndIncrement(); // 往后递增1
            this.username = username;
        }

        public int getUserId() {
            return userId;
        }

        public String getUsername() {
            return username;
        }
    }

    // 设置当前线程的用户信息
    public static void setCurrentUser(String username) {
        userInfoThreadLocal.set(new UserInfo(username)); // java ThreadLocal类自带的方法。
    }

    // 获取当前线程的用户信息
    public static UserInfo getCurrentUser() {
        return userInfoThreadLocal.get(); // java ThreadLocal类自带的方法。
    }

    // 清除当前线程的用户信息
    public static void clearCurrentUser() {
        userInfoThreadLocal.remove(); // java ThreadLocal类自带的方法。
    }

    public static void main(String[] args) {
        // 模拟多个线程访问应用，每个线程都设置自己的用户信息
        for (int i = 0; i < 5; i++) {
            final int userId = i;
            new Thread(() -> { // 匿名内部类的lamda写法。
                // 设置当前线程的用户信息
                setCurrentUser("User_" + userId);
                // 获取当前线程的用户信息并打印
                UserInfo currentUser = getCurrentUser();
                System.out.println("Thread " + Thread.currentThread().getId() +
                        " - User ID: " + currentUser.getUserId() +
                        ", Username: " + currentUser.getUsername());
                // 清除当前线程的用户信息
                clearCurrentUser(); // 清除节省空间。
            }).start();
        }
    }
}
